{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Accessing and managing users\n",
    "\n",
    "Managing accounts that will access an organization is a key aspect of a Web GIS deployment. Specific management for accounts varies depending upon a specific organization's [identity store](https://enterprise.arcgis.com/en/portal/latest/administer/linux/managing-access-to-your-portal.htm#GUID-7C7592BD-900B-49A3-87F9-CB346105308F). The API for Python provides functionality for managing user accounts. Automating management tasks such as provisioning licenses, privileges, creating and removing user accounts can save a great deal of time. The [`gis`](/python/api-reference/arcgis.gis.toc.html) module provides you with [`User`](/python/api-reference/arcgis.gis.toc.html#user) and [`UserManager`](/python/api-reference/arcgis.gis.toc.html#usermanager) classes to respresent users as objects and help you accomplish the most common tasks. \n",
    "\n",
    "As you might have observed, the API utilizes manager classes accessible from a [`GIS`](/python/api-reference/arcgis.gis.toc.html#gis) object through properties. For example, an instance of the [`ContentManager`](/python/api-reference/arcgis.gis.toc.html#contentmanager) class is returned when accessing the [`content`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.GIS.content) property on a `GIS` object. The `GIS` object employs a [`users`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.GIS.users) property to access the `UserManager`] class for managing operations and properties of `User` objects in the organization. This pattern of using properties to access specific manager classes is typical throughout the ArcGIS API for Python. Often times in guides and samples, these properties are chained together to decrease code complexity in accessing specific methods.\n",
    "\n",
    "Let's explore using the API for managing `users` within a GIS organization.  For additional resources to explore options for configuring users within a Web GIS deployment and the differences inherent in using different organizational deployments, see:\n",
    "\n",
    "* ArcGIS Enterprise - [Manage access to your portal](https://enterprise.arcgis.com/en/portal/latest/administer/linux/managing-access-to-your-portal.htm)\n",
    "* ArcGIS Online - [Invite and add members](https://doc.arcgis.com/en/arcgis-online/administer/invite-users.htm)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "toc": true
   },
   "source": [
    "<h1>Table of Contents<span class=\"tocSkip\"></span></h1>\n",
    "<div class=\"toc\"><ul class=\"toc-item\"><li><span><a href=\"#Accessing-and-managing-users\" data-toc-modified-id=\"Accessing-and-managing-users-1\"><span class=\"toc-item-num\">1&nbsp;&nbsp;</span>Accessing and managing users</a></span><ul class=\"toc-item\"><li><span><a href=\"#About-your-account\" data-toc-modified-id=\"About-your-account-1.1\"><span class=\"toc-item-num\">1.1&nbsp;&nbsp;</span>About your account</a></span></li><li><span><a href=\"#Properties-of-a-User-object\" data-toc-modified-id=\"Properties-of-a-User-object-1.2\"><span class=\"toc-item-num\">1.2&nbsp;&nbsp;</span>Properties of a <code>User</code> object</a></span></li><li><span><a href=\"#Searching-for-user-accounts\" data-toc-modified-id=\"Searching-for-user-accounts-1.3\"><span class=\"toc-item-num\">1.3&nbsp;&nbsp;</span>Searching for user accounts</a></span></li><li><span><a href=\"#Creating-new-user-accounts\" data-toc-modified-id=\"Creating-new-user-accounts-1.4\"><span class=\"toc-item-num\">1.4&nbsp;&nbsp;</span>Creating new user accounts</a></span><ul class=\"toc-item\"><li><span><a href=\"#About-user-roles\" data-toc-modified-id=\"About-user-roles-1.4.1\"><span class=\"toc-item-num\">1.4.1&nbsp;&nbsp;</span>About user roles</a></span></li><li><span><a href=\"#Managing-user-roles\" data-toc-modified-id=\"Managing-user-roles-1.4.2\"><span class=\"toc-item-num\">1.4.2&nbsp;&nbsp;</span>Managing user roles</a></span><ul class=\"toc-item\"><li><span><a href=\"#Creating-new-roles\" data-toc-modified-id=\"Creating-new-roles-1.4.2.1\"><span class=\"toc-item-num\">1.4.2.1&nbsp;&nbsp;</span>Creating new roles</a></span></li><li><span><a href=\"#Creating-a-user-with-a-custom-role\" data-toc-modified-id=\"Creating-a-user-with-a-custom-role-1.4.2.2\"><span class=\"toc-item-num\">1.4.2.2&nbsp;&nbsp;</span>Creating a user with a custom role</a></span></li><li><span><a href=\"#Listing-all-the-custom-roles-in-an-org\" data-toc-modified-id=\"Listing-all-the-custom-roles-in-an-org-1.4.2.3\"><span class=\"toc-item-num\">1.4.2.3&nbsp;&nbsp;</span>Listing all the custom roles in an org</a></span></li></ul></li></ul></li><li><span><a href=\"#Deleting-user-accounts\" data-toc-modified-id=\"Deleting-user-accounts-1.5\"><span class=\"toc-item-num\">1.5&nbsp;&nbsp;</span>Deleting user accounts</a></span><ul class=\"toc-item\"><li><span><a href=\"#Accessing-user-content\" data-toc-modified-id=\"Accessing-user-content-1.5.1\"><span class=\"toc-item-num\">1.5.1&nbsp;&nbsp;</span>Accessing user content</a></span></li><li><span><a href=\"#Reassigning-user-content\" data-toc-modified-id=\"Reassigning-user-content-1.5.2\"><span class=\"toc-item-num\">1.5.2&nbsp;&nbsp;</span>Reassigning user content</a></span></li></ul></li></ul></li></ul></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## About your account\n",
    "Let's connect to an organization and explore properties of our user account before moving on to administering other `user` accounts. We'll import the `GIS` class from `gis` module and connect to an ArcGIS Enterprise:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 599,
   "metadata": {},
   "outputs": [],
   "source": [
    "from arcgis.gis import GIS\n",
    "gis = GIS(profile=\"your_online_profile\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can access your user account by accessing the `me` property as shown below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 600,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class=\"9item_container\" style=\"height: auto; overflow: hidden; border: 1px solid #cfcfcf; border-radius: 2px; background: #f6fafa; line-height: 1.21429em; padding: 10px;\">\n",
       "                    <div class=\"item_left\" style=\"width: 210px; float: left;\">\n",
       "                       <a href='https://geosaurus.maps.arcgis.com/home/user.html?user=arcgis_python' target='_blank'>\n",
       "                        <img src='' width='200' height='133' class=\"itemThumbnail\">\n",
       "                       </a>\n",
       "                    </div>\n",
       "\n",
       "                    <div class=\"item_right\" style=\"float: none; width: auto; overflow: hidden;\">\n",
       "                        <a href='https://geosaurus.maps.arcgis.com/home/user.html?user=arcgis_python' target='_blank'><b>ArcGIS Python</b>\n",
       "                        </a>\n",
       "                        <br/><br/><b>Bio</b>: ArcGIS Python public account.&#13;&#13;Please do not change the profile information.\n",
       "                        <br/><b>First Name</b>: ArcGIS\n",
       "                        <br/><b>Last Name</b>: Python\n",
       "                        <br/><b>Username</b>: arcgis_python\n",
       "                        <br/><b>Joined</b>: December 23, 2016\n",
       "\n",
       "                    </div>\n",
       "                </div>\n",
       "                "
      ],
      "text/plain": [
       "<User username:arcgis_python>"
      ]
     },
     "execution_count": 600,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "me = gis.users.me\n",
    "me"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Similar to [`Item`](/python/api-reference/arcgis.gis.toc.html#) objects, when using the Jupyter notebook IDE, you can visualize `User` objects in rich HTML representation with thumbnails and attribute information."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Properties of a `User` object\n",
    "You can query much more information about the user account as properties on the `User` object.\n",
    "\n",
    "Consult the API [`User`](/python/api-reference/arcgis.gis.toc.html#user) class reference documentation for a complete listing of properties available on a registered account through the Python API.  In addition, the REST API [User](/rest/users-groups-and-items/user.htm#GUID-32113100-DC2C-41AA-924E-08E2CF686B00) resource documentation provides a comprehensive table of details returned in the response to a request of this resource.\n",
    "\n",
    "Let's explore some _user_ properties:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 601,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'public'"
      ]
     },
     "execution_count": 601,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "me.access"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can query a `user` object's `lastLogin` property to explore when the user last connected and compare that to the `created` property to determine any actions to take on whether the account should be deleted or the account owner contacted:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 602,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Created: 2016/12/23\n",
      "Last active: 2023/7/26\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "# convert Unix epoch time to local time\n",
    "created_time = time.localtime(me.created/1000)\n",
    "print(\"Created: {}/{}/{}\".format(created_time[0], created_time[1], created_time[2]))\n",
    "\n",
    "last_accessed = time.localtime(me.lastLogin/1000)\n",
    "print(\"Last active: {}/{}/{}\".format(last_accessed[0], last_accessed[1], last_accessed[2]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us print some more information about this account"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 603,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Description\n",
      "ArcGIS Python public account.&#13;&#13;Please do not change the profile information.\n"
     ]
    }
   ],
   "source": [
    "print(f\"Description\")\n",
    "print(f\"{me.description}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 604,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Email            First Name     Last Name      Full Name      Level  MultiFactor    Provider  User Type\n",
      "\n",
      "rsingh@esri.com  ArcGIS         Python         ArcGIS Python     2          0       arcgis    arcgisonly\n"
     ]
    }
   ],
   "source": [
    "print(f\"Email{' '*12}First Name{' '*5}Last Name{' '*6}Full Name{' '*6}Level  MultiFactor{' '*4}Provider{' '*2}User Type\")\n",
    "print(f\"\\n{me.email:17}{me.firstName:15}{me.lastName:15}{me.fullName:15}{me.level:^7}{me.mfaEnabled:^15}{me.provider:10}{me.userType}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can determine how much storage is being used by this account"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 605,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Usage: 9.04%\n"
     ]
    }
   ],
   "source": [
    "quota = me.storageQuota\n",
    "used = me.storageUsage\n",
    "pc_usage = round((used / quota)*100, 2)\n",
    "print(\"Usage: \" + str(pc_usage) + \"%\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can determine the groups the user is a member of:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 606,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Member of 272 groups\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div class=\"9item_container\" style=\"height: auto; overflow: hidden; border: 1px solid #cfcfcf; border-radius: 2px; background: #f6fafa; line-height: 1.21429em; padding: 10px;\">\n",
       "                    <div class=\"item_left\" style=\"width: 210px; float: left;\">\n",
       "                       <a href='https://geosaurus.maps.arcgis.com/home/group.html?id=00df55a8a6324c5aa4fc946d01aebb01' target='_blank'>\n",
       "                        <img src='' ' class=\"itemThumbnail\">\n",
       "                       </a>\n",
       "                    </div>\n",
       "\n",
       "                    <div class=\"item_right\" style=\"float: none; width: auto; overflow: hidden;\">\n",
       "                        <a href='https://geosaurus.maps.arcgis.com/home/group.html?id=00df55a8a6324c5aa4fc946d01aebb01' target='_blank'><b>Gallery</b>\n",
       "                        </a>\n",
       "                        <br/>\n",
       "                        <br/><b>Summary</b>: Content in this group appears on the organization gallery.\n",
       "                        <br/><b>Description</b>:  This group contains a collection of maps, apps and mobile configurations highlighted in the organization's gallery.  \n",
       "                        <br/><b>Owner</b>: arcgis_python\n",
       "                        <br/><b>Created</b>: February 15, 2017\n",
       "\n",
       "                    </div>\n",
       "                </div>\n",
       "                "
      ],
      "text/plain": [
       "<Group title:\"Gallery\" owner:arcgis_python>"
      ]
     },
     "execution_count": 606,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "user_groups = me.groups\n",
    "print(\"Member of \" + str(len(user_groups)) + \" groups\")\n",
    "\n",
    "# groups returned with rich HTML display in a notebook\n",
    "user_groups[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Searching for user accounts\n",
    "The [`search()`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.UserManager.search) method on the `UserManager` class provides the means to locate specific `users` in the organization. The `query` parameter accepts standard `ArcGIS REST API` criteria to explore the full-featured text search engine of the organization.  Consult the [**Search Reference**](/rest/users-groups-and-items/search-reference.htm) for full technical details to help set expections for results and understand how the search operation behaves.  Specific [user search](/rest/users-groups-and-items/user-search.htm) documentation will also help you determine how to construct a `query` argument to satisfy your needs. To illustrate searching, let us connect as an organization administrator and search ArcGIS Online as there are many more users available there."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 608,
   "metadata": {},
   "outputs": [],
   "source": [
    "ago_gis = GIS(profile=\"your_online_admin_profile\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 609,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "17"
      ]
     },
     "execution_count": 609,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# search the users whose username begins with _Esri_Curator_\n",
    "esri_curator_accounts = ago_gis.users.search(query=\"username:Esri_Curator*\", max_users=25, outside_org=True)\n",
    "len(esri_curator_accounts)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **NOTE:** The `max_users` argument by default is set to 100 and can be modified. Responses are limited to 10,000 results per query. See Web GIS [Considerations and limitations](/rest/users-groups-and-items/considerations-and-limitations.htm) for full details. To return more than 10,000 users, create a `query` argument using search filters and append results to a list to get the entire set of results."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each element in the list returned is a `User` object that you can query."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 610,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<User username:Esri_Curator_Basemaps>,\n",
       " <User username:Esri_Curator_Boundaries>,\n",
       " <User username:Esri_Curator_CR>,\n",
       " <User username:Esri_Curator_Demographic>,\n",
       " <User username:Esri_Curator_DK>,\n",
       " <User username:Esri_Curator_EarthObs>,\n",
       " <User username:Esri_Curator_ES>,\n",
       " <User username:Esri_Curator_GL>,\n",
       " <User username:Esri_Curator_Historical>,\n",
       " <User username:Esri_Curator_IE>,\n",
       " <User username:Esri_Curator_Imagery>,\n",
       " <User username:Esri_Curator_KR>,\n",
       " <User username:Esri_Curator_Landscape>,\n",
       " <User username:Esri_Curator_Oceans>,\n",
       " <User username:Esri_Curator_SR>,\n",
       " <User username:Esri_Curator_Transport>,\n",
       " <User username:Esri_Curator_Urban>]"
      ]
     },
     "execution_count": 610,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "esri_curator_accounts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 611,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class=\"9item_container\" style=\"height: auto; overflow: hidden; border: 1px solid #cfcfcf; border-radius: 2px; background: #f6fafa; line-height: 1.21429em; padding: 10px;\">\n",
       "                    <div class=\"item_left\" style=\"width: 210px; float: left;\">\n",
       "                       <a href='https://geosaurus.maps.arcgis.com/home/user.html?user=Esri_Curator_Basemaps' target='_blank'>\n",
       "                        <img src='' width='200' height='133' class=\"itemThumbnail\">\n",
       "                       </a>\n",
       "                    </div>\n",
       "\n",
       "                    <div class=\"item_right\" style=\"float: none; width: auto; overflow: hidden;\">\n",
       "                        <a href='https://geosaurus.maps.arcgis.com/home/user.html?user=Esri_Curator_Basemaps' target='_blank'><b>Esri Curator for Basemaps</b>\n",
       "                        </a>\n",
       "                        <br/><br/><b>Bio</b>: This account is managed by Esri, Inc. staff and used to curate Basemap content for the Living Atlas of the World.  To nominate your content for the Living Atlas, please visit livingatlas.arcgis.com/contribute.  To contact the Esri Curators, please email curatelivingatlas@esri.com.\n",
       "                        <br/><b>First Name</b>: Esri Curator\n",
       "                        <br/><b>Last Name</b>: for Basemaps\n",
       "                        <br/><b>Username</b>: Esri_Curator_Basemaps\n",
       "                        <br/><b>Joined</b>: March 31, 2015\n",
       "\n",
       "                    </div>\n",
       "                </div>\n",
       "                "
      ],
      "text/plain": [
       "<User username:Esri_Curator_Basemaps>"
      ]
     },
     "execution_count": 611,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "esri_curator_accounts[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once you know a user's `username`, you can access that object using the [**`get()`**](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.UserManager.get) method. Let us access the Esri curator account for historical maps"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 612,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class=\"9item_container\" style=\"height: auto; overflow: hidden; border: 1px solid #cfcfcf; border-radius: 2px; background: #f6fafa; line-height: 1.21429em; padding: 10px;\">\n",
       "                    <div class=\"item_left\" style=\"width: 210px; float: left;\">\n",
       "                       <a href='https://geosaurus.maps.arcgis.com/home/user.html?user=Esri_Curator_Historical' target='_blank'>\n",
       "                        <img src='' width='200' height='133' class=\"itemThumbnail\">\n",
       "                       </a>\n",
       "                    </div>\n",
       "\n",
       "                    <div class=\"item_right\" style=\"float: none; width: auto; overflow: hidden;\">\n",
       "                        <a href='https://geosaurus.maps.arcgis.com/home/user.html?user=Esri_Curator_Historical' target='_blank'><b>Esri Curator for Historical Maps</b>\n",
       "                        </a>\n",
       "                        <br/><br/><b>Bio</b>: This account is managed by Esri, Inc. staff and used to curate Historical Map content for the Living Atlas of the World.  To nominate your content for the Living Atlas, please visit livingatlas.arcgis.com/contribute.  To contact the Esri Curators, please email curatelivingatlas@esri.com.\n",
       "                        <br/><b>First Name</b>: Esri Curator\n",
       "                        <br/><b>Last Name</b>: for Historical Maps\n",
       "                        <br/><b>Username</b>: Esri_Curator_Historical\n",
       "                        <br/><b>Joined</b>: March 31, 2015\n",
       "\n",
       "                    </div>\n",
       "                </div>\n",
       "                "
      ],
      "text/plain": [
       "<User username:Esri_Curator_Historical>"
      ]
     },
     "execution_count": 612,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "esri_curator_bmaps = ago_gis.users.get(username='Esri_Curator_Historical')\n",
    "esri_curator_bmaps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating new user accounts\n",
    "You can add new users to an organization with two `UserManager` methods, [`signup()`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.UserManager.signup) or [`create()`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.UserManager.create). The `signup()` method **only** works for adding built-in accounts to an ArcGIS Enterprise deployment. It will not work with an organization deployed on ArcGIS Online. Unlike the `create()` method, `signup()` does not require administrator privileges. \n",
    "\n",
    "> Note, you can disable self-signup in your ArcGIS Enterprise which would render the `signup()` unusable if you want to configure organization access in an invite-only manner.\n",
    "\n",
    "You need administrator privileges to call the `create()` method. With an `ArcGIS Enterprise` administrator account, you can use this method to add both built-in user accounts (provider=\"_arcgis_\") and organization-specific identity store accounts (provider=_\"enterprise\"_). For an ArcGIS Online organization, you can only create users that use the built-in credential store. For built-in accounts, you provide an explicit password when the account is created, which the `user` can subsequently change upon login. For enterprise accounts using your organization-specific identiy store credentials, you can ignore the `password` parameter and your users will authenticate through that identity store. See the [understanding identity stores](https://enterprise.arcgis.com/en/portal/latest/administer/windows/managing-access-to-your-portal.htm#GUID-7C7592BD-900B-49A3-87F9-CB346105308F) documentation for details on configuring an organization for access.\n",
    "\n",
    "What any new user can do is based upon the [`privileges`](https://doc.arcgis.com/en/arcgis-online/administer/privileges-for-roles-orgs.htm) assigned through the [`role`](https://doc.arcgis.com/en/arcgis-online/administer/member-roles.htm) and [`user type`](https://doc.arcgis.com/en/arcgis-online/administer/user-types-orgs.htm) arguments of the `create()` operation. See the [User types, roles, and privileges](https://doc.arcgis.com/en/arcgis-online/administer/roles.htm) documentation for detailed descriptions on how these elements work together. A set of _privileges_ is assigned to a _role_, and then based upon those privileges a role will be compatible with certain _user_types_. Together these values determine what tasks and workflows a user can perform in an organization.\n",
    "\n",
    "The `user_type` and `role` arguments are required when running the method unless they have been configured through new member defaults. See the [Configure new member defaults](https://enterprise.arcgis.com/en/portal/latest/administer/windows/configure-new-member-defaults.htm) documentation for detailed instructions on how to set these values. The `UserManager` provides the [`user_settings`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.User.user_settings) property which allows administrators to both get and set these default values.\n",
    "\n",
    "Let us look at some examples of creating users:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Create user using _new member default_ values"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `ago_gis` connection currently represents a default administrator role connecting to ArcGIS Online. Let's first examine whether _New member defaults_ have been configured:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 613,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'role': 'org_publisher',\n",
       " 'userLicenseType': 'advancedUT',\n",
       " 'groups': ['96c9a826e654481ba2cf8f6d04137b32'],\n",
       " 'userType': 'arcgisonly',\n",
       " 'apps': [],\n",
       " 'appBundles': [],\n",
       " 'categories': []}"
      ]
     },
     "execution_count": 613,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "new_member_defaults = ago_gis.users.user_settings\n",
    "new_member_defaults"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **Note:** The `userLicenseType` key refers to the _user_type_ parameter, and the `userType` key refers to the _provider_ parameter."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 614,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create an ArcGIS Online account using `New Member Defaults`\n",
    "demo_user1 = ago_gis.users.create(username = 'new_uq_user_A9b4K1',\n",
    "                                  password = 'Ready4W8bGI$',\n",
    "                                  firstname = 'demo',\n",
    "                                  lastname = 'user',\n",
    "                                  email = 'python@esri.com',\n",
    "                                  description = 'Demonstrating how to create users using ArcGIS Python API')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 615,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class=\"9item_container\" style=\"height: auto; overflow: hidden; border: 1px solid #cfcfcf; border-radius: 2px; background: #f6fafa; line-height: 1.21429em; padding: 10px;\">\n",
       "                    <div class=\"item_left\" style=\"width: 210px; float: left;\">\n",
       "                       <a href='https://geosaurus.maps.arcgis.com/home/user.html?user=new_uq_user_A9b4K1' target='_blank'>\n",
       "                        <img src='https://geosaurus.maps.arcgis.com/home/js/arcgisonline/css/images/no-user-thumb.jpg' class=\"itemThumbnail\">\n",
       "                       </a>\n",
       "                    </div>\n",
       "\n",
       "                    <div class=\"item_right\" style=\"float: none; width: auto; overflow: hidden;\">\n",
       "                        <a href='https://geosaurus.maps.arcgis.com/home/user.html?user=new_uq_user_A9b4K1' target='_blank'><b>demo user</b>\n",
       "                        </a>\n",
       "                        <br/><br/><b>Bio</b>: None\n",
       "                        <br/><b>First Name</b>: demo\n",
       "                        <br/><b>Last Name</b>: user\n",
       "                        <br/><b>Username</b>: new_uq_user_A9b4K1\n",
       "                        <br/><b>Joined</b>: July 26, 2023\n",
       "\n",
       "                    </div>\n",
       "                </div>\n",
       "                "
      ],
      "text/plain": [
       "<User username:new_uq_user_A9b4K1>"
      ]
     },
     "execution_count": 615,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "demo_user1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can examine that the new user has been assigned the default values:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 616,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "New user: new_uq_user_A9b4K1\n",
      "--------------------------------------------------\n",
      "  role:          org_publisher\n",
      "  user type:     advancedUT\n"
     ]
    }
   ],
   "source": [
    "print(f\"New user: {demo_user1.username}\\n{'-'*50}\")\n",
    "print(f\"{' '*2}role:{' '*10}{demo_user1.role}\")\n",
    "print(f\"{' '*2}user type:{' '*5}{demo_user1.userLicenseTypeId}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **Note:** We did not enter a value for the _provider_ argument but rather accepted the default `arcgis` because the organization we're connected to utilizes built-in user security. If we were creating accounts for an organization employing an organization-specific identity store, we would specify the _provider_ argument as `enterprise` and enter an  _idpUsername_ argument as well to specify the account's username within that credential store. To learn more about this configuration, refer to this [Understand identity stores](https://enterprise.arcgis.com/en/portal/latest/administer/windows/about-configuring-portal-authentication.htm#ESRI_SECTION1_83F7B85FEF594A6B96997AF3CADF3D38) help topic."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## More about user roles\n",
    "We briefly discussed how to determine what a _user_ can do within an organization in a preceding paragraph when we talked about [user types, roles, and privileges](https://doc.arcgis.com/en/arcgis-online/administer/roles.htm). Specifically, the [member roles](https://enterprise.arcgis.com/en/portal/latest/administer/windows/member-roles.htm) define a set of privileges. The _role_ can then be assigned to a _user_ as we've demonstrated above. An organization provides _default roles_ upon installation or subscription activation. See\n",
    "\n",
    "* [ArcGIS Online Default roles](https://doc.arcgis.com/en/arcgis-online/administer/member-roles.htm#ESRI_SECTION1_C30D73392D964D51A8B606128A8A6E8F)\n",
    "* [ArcGIS Enterprise Default roles](https://enterprise.arcgis.com/en/portal/latest/administer/windows/member-roles.htm#ESRI_SECTION1_C30D73392D964D51A8B606128A8A6E8F)\n",
    "\n",
    "These default roles are configured with a set of privileges that cannot be changed. Depending upon the needs and security of your organization, you can however create [custom roles](https://doc.arcgis.com/en/arcgis-online/administer/member-roles.htm#ESRI_SECTION1_30C4E874B2A94ACFBDCC0F13400E5B4E). Depending upon the organizational deployment type, you may choose to use [ArcGIS Online templates](https://doc.arcgis.com/en/arcgis-online/administer/configure-roles.htm#ESRI_SECTION1_98A9741612744BAF9F169D255E5B6AEB) or [ArcGIS Enterprise templates](https://enterprise.arcgis.com/en/portal/latest/administer/windows/configure-roles.htm#ESRI_SECTION1_98A9741612744BAF9F169D255E5B6AEB) as a starting point for other roles, or construct specialized roles from scratch based on what your organization wants users to accomplish. \n",
    "\n",
    "To see the role for any `User` object, you can query the `role` property as previously seen:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 617,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'str'>\n",
      "org_publisher\n"
     ]
    }
   ],
   "source": [
    "demo_user1_role = demo_user1.role\n",
    "print(type(demo_user1_role))\n",
    "print(demo_user1_role)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Since this user was created with a built in role specified as a string, we get back a string with value `org_publisher`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Creating a new role\n",
    "Let's create a new _role_ in the organization. Use the [`create()`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.RoleManager.create) method on the [`RoleManager`](/python/api-reference/arcgis.gis.toc.html#rolemanager) class for this task. Specifically, we want a _role_ to assign to _users_ who we want to only publish tile layers. The _role_ should have a subset of _privileges_ of the default _User_ role and be able to create items, publish tile layers, join groups, and view and share items to the organization. This role will not have any administrator privileges. Let's demonstrate how to create a role.  In order to assign _privileges_ to a role, let's examine the exact syntax format for individual _privileges_ using the privileges property on our _user_ object:\n",
    "\n",
    "> **Note:** Even though _privileges_ is not technically a property of the `User` class, once a _user_ object is initialized, the individual _privileges_ from the _role_ hydrate the _user_ object. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To use the API to set privileges, we need to know the syntax of an individual _privilege_. Each privilege will follow this basic structure:\n",
    "\n",
    "`*:<role>:*`\n",
    "\n",
    "For example, the user _privilege_ to create and manage their own groups is called `portal:user:createGroup`. As noted above, you can observe the specific _privileges_ of a user by querying the `privileges` property. For the `demo_user1` user we created above, we can see a sample of the syntax for the privileges from the role assigned to that user by looking at the first 10 privilges:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 618,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['features:user:edit',\n",
       " 'portal:publisher:bulkPublishFromDataStores',\n",
       " 'portal:publisher:createDataPipelines',\n",
       " 'portal:publisher:publishDynamicImagery',\n",
       " 'portal:publisher:publishFeatures',\n",
       " 'portal:publisher:publishKnowledgeGraph',\n",
       " 'portal:publisher:publishScenes',\n",
       " 'portal:publisher:publishServerServices',\n",
       " 'portal:publisher:publishTiledImagery',\n",
       " 'portal:publisher:publishTiles']"
      ]
     },
     "execution_count": 618,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "demo_user1.privileges[:10]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For the custom role we want to create, we'll construct a list of specific privileges to provide the ability to publish tile layers, join and create a _group_ as well as view and share items in the organization. We'll then create a new role called `tiles_publisher` in the organization."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note**: the `privileges` parameter was provided a list of strings specifying each individual privilege. Refer to the [`privileges` property](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.Role.privileges) on the `Role` class to see a comprehensive list of possible privileges."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 631,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Role name: tiles_publisher, description: User that can publish tile layers>"
      ]
     },
     "execution_count": 631,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# create a tiles publisher role\n",
    "privilege_list = [\"portal:publisher:publishTiles\",\n",
    "                  \"portal:user:createItem\",\n",
    "                  \"portal:user:joinGroup\",\n",
    "                  \"portal:user:viewOrgGroups\",\n",
    "                  \"portal:user:viewOrgItems\",\n",
    "                  \"portal:user:shareToGroup\",\n",
    "                  \"portal:user:shareToOrg\",\n",
    "                  \"portal:user:createGroup\",\n",
    "                  \"portal:user:shareGroupToOrg\"\n",
    "                 ]\n",
    "\n",
    "tiles_pub_role = ago_gis.users.roles.create(name = 'tiles_publisher',\n",
    "                                            description = 'User that can publish tile layers',\n",
    "                                            privileges = privilege_list)\n",
    "\n",
    "tiles_pub_role"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 632,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['portal:publisher:publishTiles',\n",
       " 'portal:user:createGroup',\n",
       " 'portal:user:createItem',\n",
       " 'portal:user:joinGroup',\n",
       " 'portal:user:shareToGroup',\n",
       " 'portal:user:shareToOrg',\n",
       " 'portal:user:shareGroupToOrg,\n",
       " 'portal:user:viewOrgGroups',\n",
       " 'portal:user:viewOrgItems']"
      ]
     },
     "execution_count": 632,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# inspect the privileges of this role\n",
    "tiles_pub_role.privileges"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Creating a user with values other than new member defaults\n",
    "Let's first return a list of possible values we can enter in for the _user_type_ argument. The [`license_types`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.UserManager.license_types) property on the `UserManager` returns a dictionary with comprehensive information about each license type. We're only interested in the specific `id` value so we'll use a list comprehension to return a list of possble values to use as _user_type_ arguments:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 633,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['advancedUT',\n",
       " 'basicUT',\n",
       " 'creatorUT',\n",
       " 'editorUT',\n",
       " 'fieldWorkerUT',\n",
       " 'GISProfessionalAdvUT',\n",
       " 'GISProfessionalBasicUT',\n",
       " 'GISProfessionalStdUT',\n",
       " 'IndoorsUserUT',\n",
       " 'insightsAnalystUT',\n",
       " 'liteUT',\n",
       " 'standardUT',\n",
       " 'storytellerUT',\n",
       " 'viewerUT']"
      ]
     },
     "execution_count": 633,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "usr_types = [ut['id'] for ut in ago_gis.users.license_types]\n",
    "usr_types"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Listing all the custom roles in an org\n",
    "Next, let's inspect the possible values we can use for the _role_ argument. The default Administrator, Publisher, and User roles (see [Default roles](https://doc.arcgis.com/en/arcgis-online/administer/member-roles.htm#ESRI_SECTION1_C30D73392D964D51A8B606128A8A6E8F) for descriptions) are available by using `org_admin`, `org_publisher`, or `org_user` values as `role` arguments. To assign other default roles or [custom roles](https://doc.arcgis.com/en/arcgis-online/administer/member-roles.htm#ESRI_SECTION1_30C4E874B2A94ACFBDCC0F13400E5B4E), the values to use for the `role` argument are the `role_id` values returned from the [`all()`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.RoleManager.all) method of the `RoleManager` class. We can access a `RoleManager` object using the [`roles`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.UserManager.roles) property on the `UserManager`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 639,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Role:                    Role_id              \n",
      "---------------------    ----------------\n",
      "Viewer                   iAAAAAAAAAAAAAAA      \n",
      "Data Editor              iBBBBBBBBBBBBBBB      \n",
      "Facilitator              iCCCCCCCCCCCCCCC      \n",
      "Analyst                  53JTWAmyPz3MLgwl      \n",
      "role_6f33c               8MueSvFrA35xyg5p      \n",
      "AGOLImageryAnalysis      bl8ksdIBpwV4pa1N      \n",
      "AllNotebookPrivileges    cMH6sh9YL5RNFtat      \n",
      "UC2018_GEOG471           DmZ9fQYjofiNtJWn      \n",
      "tiles_publisher          gBC4ANXsKok12Lm4      \n",
      "guest_notebooks_basic    o4mDG5PEwU2y7tlv      \n",
      "advanced notebooks       PAH6xJAmWgYuF2vX      \n"
     ]
    }
   ],
   "source": [
    "role_mgr = ago_gis.users.roles\n",
    "print(f\"Role:{' '*20}Role_id{' '*14}\\n{'-'*21}{' '*4}{'-'*16}\")\n",
    "for role in role_mgr.all():\n",
    "    print(f\"{role.name:24} {role.role_id:22}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can see the `role_id` value for the custom role we created. Let's use that id to create a new user and assign that user to this new role:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 697,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class=\"9item_container\" style=\"height: auto; overflow: hidden; border: 1px solid #cfcfcf; border-radius: 2px; background: #f6fafa; line-height: 1.21429em; padding: 10px;\">\n",
       "                    <div class=\"item_left\" style=\"width: 210px; float: left;\">\n",
       "                       <a href='https://geosaurus.maps.arcgis.com/home/user.html?user=tiles_publisher_1' target='_blank'>\n",
       "                        <img src='https://geosaurus.maps.arcgis.com/home/js/arcgisonline/css/images/no-user-thumb.jpg' class=\"itemThumbnail\">\n",
       "                       </a>\n",
       "                    </div>\n",
       "\n",
       "                    <div class=\"item_right\" style=\"float: none; width: auto; overflow: hidden;\">\n",
       "                        <a href='https://geosaurus.maps.arcgis.com/home/user.html?user=tiles_publisher_1' target='_blank'><b>Tiles Publisher</b>\n",
       "                        </a>\n",
       "                        <br/><br/><b>Bio</b>: None\n",
       "                        <br/><b>First Name</b>: Tiles\n",
       "                        <br/><b>Last Name</b>: Publisher\n",
       "                        <br/><b>Username</b>: tiles_publisher_1\n",
       "                        <br/><b>Joined</b>: July 26, 2023\n",
       "\n",
       "                    </div>\n",
       "                </div>\n",
       "                "
      ],
      "text/plain": [
       "<User username:tiles_publisher_1>"
      ]
     },
     "execution_count": 697,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tiles_pub_user = ago_gis.users.create(username='tiles_publisher_1',\n",
    "                                      password = 'b0cb0c9f63e',\n",
    "                                      firstname = 'Tiles',\n",
    "                                      lastname = 'Publisher',\n",
    "                                      email = 'python@esri.com',\n",
    "                                      description = 'Custom role, can only publish tile layers',\n",
    "                                      role = 'gBC4ANXsKok12Lm4',\n",
    "                                      user_type='GISProfessionalAdvUT')\n",
    "\n",
    "tiles_pub_user"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Querying the `privileges` property of a `User` object returns a list of strings with fine grained privileges. When creating a `Role` object, you can pick and choose from this or refer to the [api ref doc](https://developers.arcgis.com/python/api-reference/arcgis.gis.toc.html#arcgis.gis.Role.privileges)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 698,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['portal:publisher:publishTiles',\n",
       " 'portal:user:createGroup',\n",
       " 'portal:user:createItem',\n",
       " 'portal:user:joinGroup',\n",
       " 'portal:user:shareToGroup',\n",
       " 'portal:user:viewHostedFeatureServices',\n",
       " 'portal:user:viewOrgGroups',\n",
       " 'portal:user:viewOrgItems']"
      ]
     },
     "execution_count": 698,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tiles_pub_user.privileges"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Querying the `roleId` property of a `User` returns you the custom roles' ID. You can use this to search for that role to know more details or create another user with the same role:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 699,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'gBC4ANXsKok12Lm4'"
      ]
     },
     "execution_count": 699,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tiles_pub_user.roleId"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 700,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'User that can publish tile layers'"
      ]
     },
     "execution_count": 700,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "searched_role = gis.users.roles.get_role(tiles_pub_user.roleId)\n",
    "searched_role.description"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Deleting user accounts\n",
    "Provided you are logged in as an administrator, you can delete user accounts by calling the [`delete()`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.User.delete) method on a `User` object.\n",
    "\n",
    "> **Note:** You can also use the [`delete_users()`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.UserManager.delete_users) method in the [`arcgis.gis.admin`](/python/api-reference/arcgis.gis.admin.html) submodule to delete a list of users.\n",
    "\n",
    "The Web GIS prevents you from deleting users if they own [`items`](/python/api-reference/arcgis.gis.toc.html#item) and/or [`groups`](/python/api-reference/arcgis.gis.toc.html#group). It is important to query a _user_ to investigate whether they own content.\n",
    "\n",
    "### Accessing user content\n",
    "As an _administrator_, you can view the _folders_ and _items_ owned by any user. Get the `User` object and then query the [`items()`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.User.items) method and  [`folders`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.User.folders) property."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 702,
   "metadata": {},
   "outputs": [],
   "source": [
    "pub1_user = ago_gis.users.get(\"publisher1_uq\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### List the folders owned by a user"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 703,
   "metadata": {},
   "outputs": [],
   "source": [
    "publisher_folder_list = pub1_user.folders"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 704,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'username': 'publisher1_uq',\n",
       "  'id': '01bf52ddd49b45caa9c5a6ef263d8352',\n",
       "  'title': 'Arkansas data',\n",
       "  'created': 1690416367000},\n",
       " {'username': 'publisher1_uq',\n",
       "  'id': 'b73d3fd029a14fcda72ba1af8fdbdd3c',\n",
       "  'title': 'chicago_data',\n",
       "  'created': 1690415221000},\n",
       " {'username': 'publisher1_uq',\n",
       "  'id': 'ff046ef454c04788b53b96261d5803ef',\n",
       "  'title': 'historical_data',\n",
       "  'created': 1690415732000}]"
      ]
     },
     "execution_count": 704,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "publisher_folder_list"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### List the content in a user's root folder"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In addition to folder a user may have created, each user also has a root folder that contains those items that have not been explicitly added to a folder:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 705,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total number of items in root folder: 3\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div class=\"item_container\" style=\"height: auto; overflow: hidden; border: 1px solid #cfcfcf; border-radius: 2px; background: #f6fafa; line-height: 1.21429em; padding: 10px;\">\n",
       "                    <div class=\"item_left\" style=\"width: 210px; float: left;\">\n",
       "                       <a href='https://geosaurus.maps.arcgis.com/home/item.html?id=da549a4928c643ddb6b44c1ed1e113fa' target='_blank'>\n",
       "                        <img src='http://static.arcgis.com/images/desktopapp.png' class=\"itemThumbnail\">\n",
       "                       </a>\n",
       "                    </div>\n",
       "\n",
       "                    <div class=\"item_right\"     style=\"float: none; width: auto; overflow: hidden;\">\n",
       "                        <a href='https://geosaurus.maps.arcgis.com/home/item.html?id=da549a4928c643ddb6b44c1ed1e113fa' target='_blank'><b>Colorado Mountain Peaks</b>\n",
       "                        </a>\n",
       "                        <br/>Data about peaks in the Rocky Mountains of Colorado.<img src='https://geosaurus.maps.arcgis.com/home/js/jsapi/esri/css/images/item_type_icons/datafiles16.png' style=\"vertical-align:middle;\" width=16 height=16>Shapefile by publisher1_uq\n",
       "                        <br/>Last Modified: July 26, 2023\n",
       "                        <br/>0 comments, 1 views\n",
       "                    </div>\n",
       "                </div>\n",
       "                "
      ],
      "text/plain": [
       "<Item title:\"Colorado Mountain Peaks\" type:Shapefile owner:publisher1_uq>"
      ]
     },
     "execution_count": 705,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "publisher1_root_folder_items = pub1_user.items()\n",
    "print(\"Total number of items in root folder: \" + str(len(publisher1_root_folder_items)))\n",
    "\n",
    "#access the first item for a sample\n",
    "publisher1_root_folder_items[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 706,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Root folder: publisher1_uq\n",
      " Item Title                      Item Type                \n",
      " ---------------------------     -------------------------\n",
      "  Colorado Mountain Peaks        Shapefile                \n",
      "  Colorado Mountain Peaks        Feature Service          \n",
      "  World Country Boundary Data    Service Definition       \n",
      "\n",
      "\n",
      "Folder: Arkansas data\n",
      " Item Title                      Item Type                \n",
      " ---------------------------     -------------------------\n",
      "  AR Boundaries                  Shapefile                \n",
      "  AR Boundaries                  Feature Service          \n",
      "\n",
      "\n",
      "Folder: chicago_data\n",
      " Item Title                      Item Type                \n",
      " ---------------------------     -------------------------\n",
      "  Chicago Accidents              CSV                      \n",
      "  Chicago Accidents              Feature Service          \n",
      "  Chicago Accidents Volume2      CSV                      \n",
      "  Chicago Accidents Volume2      Feature Service          \n",
      "\n",
      "\n",
      "Folder: historical_data\n",
      " Item Title                      Item Type                \n",
      " ---------------------------     -------------------------\n",
      "  Ancient Woodland Inventory UK  Shapefile                \n",
      "  Ancient Woodland Inventory UK  Feature Service          \n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# list all items for the user\n",
    "print(f\"Root folder: {pub1_user.username}\")\n",
    "print(f\" Item Title{' '*22}Item Type{' '*16}\\n {'-'*27}{' '*5}{'-'*25}\")\n",
    "for root_item in publisher1_root_folder_items:\n",
    "    print(f\" {' '*1}{root_item.title:31}{root_item.type:25}\")\n",
    "print(\"\\n\")\n",
    "for pub_folder in publisher_folder_list:\n",
    "    print(f\"Folder: {pub_folder['title']}\")\n",
    "    print(f\" Item Title{' '*22}Item Type{' '*16}\\n {'-'*27}{' '*5}{'-'*25}\")\n",
    "    for folder_item in pub1_user.items(folder=pub_folder['title']):\n",
    "        print(f\" {' '*1}{folder_item.title:31}{folder_item.type:25}\")\n",
    "    print(\"\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As an administrator within an organizaion, you are able to query the contents of another user without knowing that user's password or logging in as that user."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Reassigning user content\n",
    "When the time comes to delete a user account, you can filter these items and choose to preserve some and delete the content that is no longer needed. We're going to delete the `publisher1_uq` account we've just looked at, keeping only some accident data we plan to analyze later.\n",
    "\n",
    "> **Note:** It is import to consider the _privileges_ of each _user_. If the receiving _user_ does not have the proper permissions to be reassigned an item, errors may occur. \n",
    "\n",
    "> **Note:** If an item's sharing level is _private_ but shared with _groups_, the receiving _user_ must have the appropriate sharing access to all groups the item is shared with.\n",
    "\n",
    "We'll reassign the source [`Feature Layer`](/python/api-reference/arcgis.features.toc.html#featurelayer) items about accidents in Chicago to the `tiles_pub_user` user we created earlier. We'll use the [`advanced_search()`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.ContentManager.advanced_search) method to query for specific item titles and types, and reassign these items. You can reassign specific items to another user by calling the [`reassign_to()`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.Item.reassign_to) method on the `Item` object. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 707,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<Item title:\"Chicago Accidents\" type:Feature Layer Collection owner:publisher1_uq>,\n",
       " <Item title:\"Chicago Accidents Volume2\" type:Feature Layer Collection owner:publisher1_uq>]"
      ]
     },
     "execution_count": 707,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chi_flyr_items = ago_gis.content.advanced_search(query=f\"owner:{pub1_user.username} title:Chicago type:Feature Service\", )[\"results\"]\n",
    "chi_flyr_items"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 709,
   "metadata": {},
   "outputs": [],
   "source": [
    "for flyr_item in chi_flyr_items:\n",
    "        flyr_item.reassign_to(target_owner=tiles_pub_user)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's now query the _tiles_pub_user_ to verify the items were successfully assigned."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 710,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<Item title:\"Chicago Accidents\" type:CSV owner:tiles_publisher_1>,\n",
       " <Item title:\"Chicago Accidents\" type:Feature Layer Collection owner:tiles_publisher_1>,\n",
       " <Item title:\"Chicago Accidents Volume2\" type:CSV owner:tiles_publisher_1>,\n",
       " <Item title:\"Chicago Accidents Volume2\" type:Feature Layer Collection owner:tiles_publisher_1>]"
      ]
     },
     "execution_count": 710,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tiles_pub_user.items()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice how the _related_items_ for the Feature Layer are automatically assigned as part of the operation."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Delete user and reassign items"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we are left with a few more items which we want to reassign to a _user_ named `arcgis_python` in our organization. We can call the `reassign_to()` method of the `User` object or we can call the [`delete()`](/python/api-reference/arcgis.gis.toc.html#arcgis.gis.User.delete) method on the `User` object and provide an argument to the `reassign_to` parameter to accomplish the same task. First let's take a look at the remaining items owned by the `publisher1_uq` _user_:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 711,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'total': 7,\n",
       " 'start': 1,\n",
       " 'num': 100,\n",
       " 'nextStart': -1,\n",
       " 'results': [<Item title:\"Ancient Woodland Inventory UK\" type:Feature Layer Collection owner:publisher1_uq>,\n",
       "  <Item title:\"Ancient Woodland Inventory UK\" type:Shapefile owner:publisher1_uq>,\n",
       "  <Item title:\"AR Boundaries\" type:Feature Layer Collection owner:publisher1_uq>,\n",
       "  <Item title:\"AR Boundaries\" type:Shapefile owner:publisher1_uq>,\n",
       "  <Item title:\"Colorado Mountain Peaks\" type:Shapefile owner:publisher1_uq>,\n",
       "  <Item title:\"Colorado Mountain Peaks\" type:Feature Layer Collection owner:publisher1_uq>,\n",
       "  <Item title:\"World Country Boundary Data\" type:Service Definition owner:publisher1_uq>]}"
      ]
     },
     "execution_count": 711,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ago_gis.content.advanced_search(query=f\"owner:{pub1_user.username}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **Note:** The `advanced_search()` method searches all folders owned by a _user_. When using the `reassign_to` parameter in the `delete()` method, the output items are stored in folders named after the original _username_ followed by the _folder title_, including a folder named _username_root_ for items that are stored in the original user's root folder."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we'll use the `delete()` method to remove the `publisher1_uk` user while reassigning their items:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 712,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 712,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pub1_user.delete(reassign_to='arcgis_python')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We'll search for the user to verify the deletion:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 713,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'total': 0, 'start': 1, 'num': 10, 'nextStart': -1, 'results': []}"
      ]
     },
     "execution_count": 713,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ago_gis.users.advanced_search(query=f\"owner:{pub1_user.username}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Thus, we have successfully deleted a user after taking care of that user's content."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.17"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": true,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
